﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Mes_app_control
{
    class SocketWrapper : IDisposable
    {
        private string ip = "127.0.0.1";
        private int port = 502;
        private int timeout = 1000;

        private Socket socket = null;

        private object lockWrite = new object();
        private readonly ManualResetEvent TimeoutObject = new ManualResetEvent(false);

        public string IP
        {
            get
            {
                return ip;
            }
            set
            {
                ip = value;
            }
        }
        public int Port
        {
            get
            {
                return port;
            }
            set
            {
                port = value;
            }
        }
        public int TimeOut
        {
            get
            {
                return timeout;
            }
            set
            {
                timeout = value;
            }
        }

        public bool Connect()
        {
            try
            {
                this.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                this.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout);

                IPEndPoint ipAddr = new IPEndPoint(IPAddress.Parse(ip), port);
                socket.BeginConnect(ipAddr, CallBackMethod, socket);
                if (TimeoutObject.WaitOne(1000, false))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                return false;
            }
            return false;
        }

        private void CallBackMethod(IAsyncResult asyncresult)
        {
            //使阻塞的线程继续        
            TimeoutObject.Set();
        }

        public void Disconnect()
        {
            this.socket.Close();
        }

        public byte[] Read(int length)
        {
            byte[] buffer = new byte[length];
            int bytesRead = this.socket.Receive(buffer); 

            if (bytesRead < buffer.Length)
            {
                byte[] data = new byte[bytesRead];
                Array.Copy(buffer, data, bytesRead);
                return data;
            }
            return buffer;
        }

        public void Write(byte[] data)
        {
            try
            {
                Monitor.Enter(lockWrite);
                this.socket.Send(data);
            }
            catch (Exception e)
            {
            }
            finally
            {
                Monitor.Exit(lockWrite);
            }
        }

        public void Dispose()
        {
            if (this.socket != null)
            {
                this.socket.Close();
            }
        }
    }
}
